home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / bfd / cpu-h8300.c < prev    next >
C/C++ Source or Header  |  1992-09-11  |  10KB  |  410 lines

  1. /* BFD library support routines for the Hitachi H8/300 architecture.
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Hacked by Steve Chamberlain of Cygnus Support.
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "bfd.h"
  22. #include "sysdep.h"
  23. #include "libbfd.h"
  24.  
  25. #define DEFINE_TABLE 
  26. #include "h8300-opcode.h"
  27.  
  28. #define MAXSAME 14
  29.  
  30. static struct h8_opcode * h8_opcodes_sorted[256][MAXSAME];
  31.  
  32. /* Run through the opcodes and sort them into order to make them easy
  33.    to disassemble
  34.  */
  35. static void
  36. DEFUN_VOID(bfd_h8_disassemble_init)
  37. {
  38.   unsigned int i;    
  39.   struct h8_opcode *p; 
  40.     
  41.   for (p = h8_opcodes; p->name; p++) {    
  42.     int where = 0;
  43.     int n1 = 0;
  44.     int n2 = 0;
  45.     int n3 = 0;
  46.     int n4= 0;
  47.     if ((int)p->data.nib[0] < 16) {
  48.       n1 =(int) p->data.nib[0] ;
  49.     } else n1 = 0;
  50.     if ((int)p->data.nib[1] < 16) {
  51.       n2 = (int) p->data.nib[1];
  52.     }else n2 = 0;
  53.  
  54.     for (i = 0; i < MAXSAME; i++) {
  55.       int j = n1 * 16 + n2;
  56.       if (h8_opcodes_sorted[j][i] == (struct h8_opcode *)NULL) {
  57.     h8_opcodes_sorted[j][i] = p;
  58.     break;
  59.       }
  60.     }
  61.     
  62.     if (i==MAXSAME)abort();
  63.  
  64.     /* Just make sure there are an even number of nibbles in it, and
  65.        that the count is the same s the length */
  66.     for (i = 0; p->data.nib[i] != E; i++) ;
  67.     if (i & 1) abort();
  68.     if (i/2 != p->length) abort();
  69.   }
  70.   for (i = 0; i < 256; i++) 
  71.       {
  72.     if (h8_opcodes_sorted[i][0]) 
  73.       p = h8_opcodes_sorted[i][0];
  74.     else h8_opcodes_sorted[i][0] = p;
  75.       }
  76. }
  77.  
  78.  
  79. unsigned int
  80. DEFUN(bfd_h8_disassemble,(addr, data, stream),
  81. bfd_vma addr AND
  82. CONST bfd_byte *data AND
  83. FILE *stream)
  84. {
  85.   /* Find the first entry in the table for this opcode */
  86.   CONST static char *regnames[] = {
  87.     "r0h","r1h","r2h","r3h","r4h","r5h","r6h","r7h",
  88.     "r0l","r1l","r2l","r3l","r4l","r5l","r6l","r7l" };
  89.  
  90.   int rs = 0;
  91.   int rd = 0;
  92.   int rdisp = 0;
  93.   int abs = 0;
  94.   struct h8_opcode **p = h8_opcodes_sorted[(unsigned)(data[0])];
  95.   struct h8_opcode *q;
  96.  
  97.   /* Find the exact opcode/arg combo */
  98.   while (*p) {
  99.     op_type *nib;
  100.     unsigned int len = 0;
  101.     q = *p++;
  102.     nib  =q->data.nib;
  103.     while (*nib != E) {
  104.       op_type looking_for = *nib;
  105.       int thisnib = data[len>>1] ;
  106.       thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib >> 4) & 0xf);
  107.       if ((int)looking_for & (int)B31) {
  108.     if (((int)thisnib & 0x8) ==0) goto fail;
  109.     looking_for = (op_type)((int)looking_for &  ~(int)B31);
  110.       }
  111.       if ((int)looking_for & (int)B30) {
  112.     if (((int)thisnib & 0x8) !=0) goto fail;
  113.     looking_for = (op_type)((int)looking_for &  ~(int)B30);
  114.       }
  115.       switch (looking_for) {
  116.       case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
  117.       case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
  118.     if ((int)looking_for != thisnib) goto fail;
  119.     break;
  120.       case ABS16SRC:
  121.       case ABS16DST:
  122.       case DISPSRC:
  123.       case DISPDST:
  124.       case IMM16:
  125.     abs = (data[len>>1]) * 256 + data[(len+2)>>1];
  126.     len+=3;
  127.     nib+=3;
  128.     break;
  129.       case DISPREG:
  130.     rdisp = thisnib; 
  131.     break;
  132.       case KBIT:
  133.     abs = thisnib == 0x80 ? 2:1;
  134.     break;
  135.       case IMM8:
  136.       case ABS8SRC:
  137.       case ABS8DST:
  138.       case DISP8:
  139.     abs= data[len>>1];
  140.     len++;
  141.     nib++;
  142.     break;
  143.       case IMM3:
  144.     abs = thisnib ;
  145.     break;
  146.       case RS8:
  147.       case RS16:
  148.       case RSINC:
  149.       case RSIND:
  150.     rs = thisnib;
  151.     break;
  152.       case RD16:
  153.       case RDDEC:
  154.       case RD8:
  155.       case RDIND:
  156.     rd = thisnib;
  157.     break;
  158.       default:
  159.     fprintf(stream, "Dont understand \n");
  160.     goto found;
  161.       }
  162.       len++;
  163.       nib++;
  164.     }
  165.     goto found;
  166.   fail: 
  167.     ;
  168.  
  169.   }
  170.   fprintf(stream, "%02x %02x        .word\tH'%x,H'%x\n",
  171.       data[0], data[1],
  172.       data[0], data[1]);
  173.   return 2;
  174.  found:;
  175.     { int i;
  176.  
  177.       for (i = 0; i < q->length; i++) {
  178.     fprintf(stream, "%02x ", data[i]);
  179.       }
  180.       for (; i < 6; i++) {
  181.     fprintf(stream, "   ");
  182.       }
  183.     }
  184.   fprintf(stream, "%s\t",q->name);
  185.   /* Now print out the args */
  186.     {
  187.       op_type *args = q->args.nib;
  188.       int hadone = 0;
  189.       while (*args != E) {
  190.     if (hadone)
  191.       fprintf(stream, ",");
  192.     switch ((int)(*args) & ~((int)B30|(int)B31)) {
  193.     case IMM16:
  194.     case IMM8:
  195.     case IMM3:
  196.       fprintf(stream, "#H'%x", (unsigned)abs); break;
  197.     case RD8:
  198.       fprintf(stream, "%s", regnames[rd]); break;
  199.     case RS8:
  200.       fprintf(stream, "%s",regnames[rs]); break;
  201.     case RD16:
  202.       fprintf(stream, "r%d", rd& 0x7); break;
  203.     case RS16:
  204.       fprintf(stream, "r%d", rs & 0x7); break;
  205.     case RSINC:
  206.       fprintf(stream, "@r%d+", rs & 0x7); break;
  207.     case RDDEC:
  208.       fprintf(stream, "@-r%d", rd & 0x7); break;
  209.     case RDIND: 
  210.       fprintf(stream, "@r%d", rd & 0x7); break;
  211.     case RSIND:
  212.       fprintf(stream, "@r%d",rs & 0x7); break;
  213.     case ABS8SRC:
  214.     case ABS16SRC:
  215.     case ABS16DST:
  216.     case ABS8DST:
  217.       fprintf(stream, "@H'%x", (unsigned)abs); break;
  218.     case DISP8:
  219.       fprintf(stream, ".%s%d (%x)",(char)abs>0 ? "+" :"", (char)abs,
  220.           addr + (char)abs);
  221.       break;
  222.     case DISPSRC:
  223.     case DISPDST:
  224.       fprintf(stream, "@(%d,r%d)", abs, rdisp & 0x7); break;
  225.     case CCR:
  226.       fprintf(stream, "ccr"); break;
  227.     case KBIT:
  228.       fprintf(stream, "#%d",abs); break;
  229.     default:
  230.       abort();
  231.     }
  232.     hadone = 1;
  233.     args++;
  234.       }
  235.     }
  236.   return q->length;
  237. }
  238.  
  239.  
  240.  
  241. unsigned int DEFUN(print_insn_h8300,(addr, data, file),
  242. bfd_vma addr AND
  243. CONST char *data AND
  244. PTR file)
  245. {
  246.   static boolean init;
  247.   if (!init) {
  248.     bfd_h8_disassemble_init();
  249.     init= 1;
  250.   }
  251.  
  252.   return   bfd_h8_disassemble(addr, (bfd_byte *)data, file);
  253. }
  254.  
  255. /* 
  256. Relocations for the H8
  257.  
  258. */
  259. static bfd_reloc_status_type 
  260. DEFUN(howto16_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  261. bfd *abfd AND
  262. arelent *reloc_entry AND
  263. asymbol *symbol_in AND
  264. unsigned char *data AND
  265. asection *ignore_input_section)
  266. {
  267.   long relocation = 0;
  268.   bfd_vma addr = reloc_entry->address;
  269.   long x = bfd_get_16(abfd, (bfd_byte *)data + addr);
  270.  
  271.   HOWTO_PREPARE(relocation, symbol_in);
  272.  
  273.   x = (x + relocation + reloc_entry->addend);
  274.  
  275.   bfd_put_16(abfd, x, (bfd_byte *)data + addr);
  276.   return bfd_reloc_ok;
  277. }
  278.  
  279.  
  280. static bfd_reloc_status_type 
  281. DEFUN(howto8_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  282. bfd *abfd AND
  283. arelent *reloc_entry AND
  284. asymbol *symbol_in AND
  285. unsigned char *data AND
  286. asection *ignore_input_section)
  287. {
  288.   long relocation = 0;
  289.   bfd_vma addr = reloc_entry->address;
  290.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  291.  
  292.   HOWTO_PREPARE(relocation, symbol_in);
  293.  
  294.   x = (x + relocation + reloc_entry->addend);
  295.  
  296.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  297.   return bfd_reloc_ok;
  298. }
  299.  
  300.  
  301. static bfd_reloc_status_type 
  302. DEFUN(howto8_FFnn_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  303. bfd *abfd AND
  304. arelent *reloc_entry AND
  305. asymbol *symbol_in AND
  306. unsigned char *data AND
  307. asection *ignore_input_section)
  308. {
  309.   long relocation = 0;
  310.   bfd_vma addr = reloc_entry->address;
  311.  
  312.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  313.   abort();
  314.   HOWTO_PREPARE(relocation, symbol_in);
  315.  
  316.   x = (x + relocation + reloc_entry->addend);
  317.  
  318.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  319.   return bfd_reloc_ok;
  320. }
  321.  
  322. static bfd_reloc_status_type 
  323. DEFUN(howto8_pcrel_callback,(abfd, reloc_entry, symbol_in, data, ignore_input_section),
  324. bfd *abfd AND
  325. arelent *reloc_entry AND
  326. asymbol *symbol_in AND
  327. unsigned char *data AND
  328. asection *ignore_input_section)
  329. {
  330.   long relocation = 0;
  331.   bfd_vma addr = reloc_entry->address;
  332.   long x = bfd_get_8(abfd, (bfd_byte *)data + addr);
  333.   abort();
  334.   HOWTO_PREPARE(relocation, symbol_in);
  335.  
  336.   x = (x + relocation + reloc_entry->addend);
  337.  
  338.   bfd_put_8(abfd, x, (bfd_byte *)data + addr);
  339.   return bfd_reloc_ok;
  340. }
  341.  
  342.  
  343. static reloc_howto_type howto_16
  344.   = NEWHOWTO(howto16_callback,"abs16",1,0,0);
  345. static reloc_howto_type howto_8
  346.   = NEWHOWTO(howto8_callback,"abs8",0,0,0);
  347.  
  348. static reloc_howto_type howto_8_FFnn
  349.   = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,0,0);
  350.  
  351. static reloc_howto_type howto_8_pcrel
  352.   = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,1,1);
  353.  
  354.  
  355.  
  356. static CONST struct reloc_howto_struct *
  357. DEFUN(local_bfd_reloc_type_lookup,(arch, code),
  358.  CONST struct bfd_arch_info *arch AND
  359.  bfd_reloc_code_type code)
  360. {
  361.   switch (code) {
  362.   case BFD_RELOC_16:
  363.     return &howto_16;
  364.   case BFD_RELOC_8_FFnn:
  365.     return &howto_8_FFnn;
  366.   case BFD_RELOC_8:
  367.     return &howto_8;
  368.   case BFD_RELOC_8_PCREL:
  369.     return &howto_8_pcrel;
  370.   }
  371.   return (reloc_howto_type *)NULL;
  372. }
  373.  
  374. int bfd_default_scan_num_mach();
  375.  
  376. static boolean 
  377. DEFUN(h8300_scan,(info, string),
  378. CONST struct bfd_arch_info *info AND
  379. CONST char *string)
  380. {
  381.   if (strcmp(string,"h8300") == 0) return true;
  382.   if (strcmp(string,"H8300") == 0) return true;
  383.   if (strcmp(string,"h8/300") == 0) return true;
  384.   if (strcmp(string,"H8/300") == 0) return true;
  385.   return false;
  386. }
  387.  
  388. static bfd_arch_info_type arch_info_struct = 
  389.   {
  390.     16,    /* 16 bits in a word */
  391.     16,    /* 16 bits in an address */
  392.     8,    /* 8 bits in a byte */
  393.     bfd_arch_h8300,
  394.     0,    /* only 1 machine */
  395.     "H8/300", /* arch_name  */
  396.     "H8/300", /* printable name */
  397.     true,    /* the default machine */
  398.     bfd_default_compatible,
  399.     h8300_scan,
  400.     print_insn_h8300,
  401.     local_bfd_reloc_type_lookup,
  402.     0,
  403.   };
  404.  
  405. void
  406. DEFUN_VOID(bfd_h8300_arch)
  407. {
  408.   bfd_arch_linkin(&arch_info_struct);
  409. }
  410.